// JavaScript Document

	
	
	
	
	
	
	//------------------------------------------------------------
	// ScrollBar definition
	//------------------------------------------------------------
	
	var ScrollBarVertical = (function( topImage, centerImage, btmImage, onComplete )
	{
		
		var loadCount, _this, minScrollBarSize;
		loadCount = 0;

		this.top, this.center, this.btm, this.bar;
		
		_this = this;
		
		this.top = document.createElement("div");
		this.top.style.position = "absolute";
		this.top.style.width = "100%";
		this.top.appendChild( new NSImage( topImage, onImgLoaded ) );
		
		this.center = document.createElement("div");
		this.center.style.position = "absolute";
		this.center.style.width = "100%";
		this.center.appendChild( new NSImage( centerImage, onImgLoaded ) );
		
		this.btm = document.createElement("div");
		this.btm.style.position = "absolute";
		this.btm.style.width = "100%";
		this.btm.appendChild( new NSImage( btmImage, onImgLoaded ) );
		
		this.bar = document.createElement( "div" );
		this.bar.style.position = "absolute";
		this.bar.appendChild( this.top );
		this.bar.appendChild( this.center );
		this.bar.appendChild( this.btm );
		
		function onImgLoaded()
		{
			loadCount++;
			
			
			if( loadCount == 3 )
			{
				
				_this.top.height = _this.top.firstChild.height;
				_this.center.height = _this.center.firstChild.height;
				_this.btm.height = _this.btm.firstChild.height;
				
				_this.top.firstChild.style.position = "absolute";
				_this.top.firstChild.style.left = "0";
				_this.center.firstChild.style.position = "absolute";
				_this.center.firstChild.style.left = "0";
				_this.btm.firstChild.style.position = "absolute";
				_this.btm.firstChild.style.left = "0";
				
				_this.center.style.top = _this.top.height+"px";
				_this.btm.style.top = (_this.top.height + _this.center.height) + "px";
				minScrollBarSize = _this.top.height + _this.center.height + _this.btm.height;
				
				if( onComplete != null )
				{
					onComplete( _this );
				}
				
			}
		}
		
		
		this.setSize = function( w, h )
		{
			if( h != null )
			{
				this.center.firstChild.width = 5;
				this.center.firstChild.height = Math.max( h-this.top.height-this.btm.height, minScrollBarSize-this.top.height-this.btm.height );
				this.center.height = this.center.firstChild.height;
				this.btm.style.top = ( this.top.height + this.center.height ) + "px";
			}
		}
		
		
		this.setXY = function( x, y )
		{
			this.bar.style.left = x+"px";
			this.bar.style.top = y+"px";
		}
		
		this.getHeight = function()
		{
			return 	this.top.height+this.center.height+this.btm.height;
		}
		
		
		return _this;
		
	});
	
	
	
	
	
	
	//------------------------------------------------------------
	// ScrollComponent definition
	//------------------------------------------------------------
	
	var ScrollComponentVertical = ( function( scrollDiv, contentsDiv, scrollBar ){
		
		//----------- public vars

		// 스크롤 위치 
		this.scrollPosY = 0;
		
		// 최소스크롤 값.
		this.minScrollPos = 0;
		
		// 최대 스크롤 값.
		this.maxScrollPos = 0;
		
		// 컨테이너
		this.scrollContainer = scrollDiv;
		this.contentsContainer = contentsDiv;
		
		this.needScroll = false;
		this.contentsHeight = -1;
		this.gapItem = 0;
						
		//----------- private vars
		
		var _this = this;
		
		// 버퍼 스크롤 값들.
		var initPosY = 0;
		var prevPosY = 0;
		var prevPosY2 = 0;
		var prevPosY3 = 0;
		
		// 현재 스크롤을 위한 힘.
		var currentScrollPow = 0;
		
		// 현재 mouseMove 중인지 체크.
		var isMoveEnter = false;
		
		
		var touchStartPos = {};
		var touchEndPos = {};
		var mouseEnabled = false;
		
		
		
		//--------------------------------------------------------
		// public functions
		//--------------------------------------------------------
		
		this.resetScroll = function( duration )
		{
			var target, css;
			
			target = _this.contentsContainer;
			if( duration == null ) duration = 0.3;
			css = {};
			
			css.marginTop = 0;
			_this.scrollPosY = 0;
		
			try{ TweenMax.killTweensOf( target ); }catch(e){}
			TweenMax.to( target , duration, {css:css, ease:Cubic.easeOut, onUpdate:updateScrollBar, onComplete : onScrollComplete} );
		}
		
		
		this.setScrollLeft = function( marginTop )
		{
			this.contentsContainer.style.marginTop = marginTop + "px";
			updateScrollBar();
		}
		
		
		this.setMouseEnabled = function( bool )
		{
			mouseEnabled = bool;
			
			if( mouseEnabled == true )
			{
				this.scrollContainer.addEventListener( "touchstart", onTouchStart, false );
				this.scrollContainer.addEventListener( "mousedown", onTouchStart, false );
				
				this.scrollContainer.removeEventListener( "touchstart", onTouchPrevent, true );
				this.scrollContainer.removeEventListener( "mousedown", onTouchPrevent, true );
				this.scrollContainer.removeEventListener( "touchend", onTouchPrevent, true );
				this.scrollContainer.removeEventListener( "mouseup", onTouchPrevent, true );
				this.scrollContainer.removeEventListener( "click", onTouchPrevent, true );
			}
			else
			{
				this.scrollContainer.removeEventListener( "touchstart", onTouchStart, false );
				this.scrollContainer.removeEventListener( "mousedown", onTouchStart, false );
				
				this.scrollContainer.addEventListener( "touchstart", onTouchPrevent, true );
				this.scrollContainer.addEventListener( "mousedown", onTouchPrevent, true );
				this.scrollContainer.addEventListener( "touchend", onTouchPrevent, true );
				this.scrollContainer.addEventListener( "mouseup", onTouchPrevent, true );
				this.scrollContainer.addEventListener( "click", onTouchPrevent, true );
			}
		}
		
		var onTouchPrevent = function( e )
		{
			e.preventDefault();
		}
		
		
		
		
		
		
		//--------------------------------------------------------
		// private functions
		//--------------------------------------------------------
		
		var updateScrollBar = function()
		{
			
			var totalScrollHeight, barMoveHeight, currentY, scrollBarPos, scrollBarHeight;
			
			scrollBarHeight = _this.scrollContainer.clientHeight/_this.contentsContainer.clientHeight*_this.scrollContainer.clientHeight;
			scrollBar.setSize( null, scrollBarHeight );
			
			totalScrollHeight = _this.contentsContainer.clientHeight - _this.scrollContainer.clientHeight;
			barMoveHeight = _this.scrollContainer.clientHeight - scrollBar.getHeight();
			currentY = _this.contentsContainer.style.marginTop;
			currentY = Number( currentY.slice( 0, currentY.length-2 ) );
			
			
			scrollBarPos = barMoveHeight*(-currentY/totalScrollHeight);
			
			if( scrollBarPos < 0 )
			{
				scrollBar.setSize( null, scrollBarHeight-(-scrollBarPos) );
				scrollBarPos = 0;
			}
			else if( scrollBarPos > barMoveHeight )
			{
				scrollBar.setSize( null, scrollBarHeight-(scrollBarPos-barMoveHeight) );
				scrollBarPos = barMoveHeight+(scrollBarPos-barMoveHeight);
			}
			
			
			scrollBar.setXY( null, scrollBarPos );
			
			
		}
		
		
		
		//----------- private functions
			
		var onMoveEnter = function()
		{
			if( isMoveEnter == false ) return;
			
			if( checkOutOfBound() )
			{
				currentScrollPow *= 0.3;
			}
			
			_this.scrollPosY += currentScrollPow;
			_this.contentsContainer.style.marginTop = _this.scrollPosY + "px";
			
			
			
			// 마우스 다운상태로 가만히 있을경우 파워를 급격히 감소. 
			if( Math.abs( currentScrollPow ) < 1 )
			{
				currentScrollPow *= 0.4;
			}
			
			updateScrollBar();
			
			if( Math.abs( currentScrollPow ) > 1 && isMoveEnter == true )
			{
				setTimeout( onMoveEnter, 1000/60 );
			}
			else
			{
				isMoveEnter = false;
			}
		}
		
		
		var onEnter = function()
		{
			if( checkOutOfBound() )
			{
				currentScrollPow *= 0.2;
			}
			
			_this.scrollPosY += currentScrollPow;
			_this.contentsContainer.style.marginTop = _this.scrollPosY + "px";
			currentScrollPow *= 0.9;
			
			updateScrollBar();
			
			
			if( _this.needScroll == false )
			{
				readyForScrollInitPos();
			}
			else if( Math.abs( currentScrollPow ) > 1 )
			{
				if( checkOutOfBound() )
				{
					readyForScrollInitPos();
				}
				else
				{
					setTimeout( onEnter, 17 );
				}
			}
			else
			{
				if( checkOutOfBound() )
				{
					readyForScrollInitPos();
				}
				else
				{
					onScrollComplete();	
				}
			}
			
		}
		
		
		
		var readyForScrollInitPos = function()
		{
			
			var target, duration, css;
			
			target = _this.contentsContainer;
			duration = Math.abs( currentScrollPow )/600;
			css = {};
			css.marginTop = (currentScrollPow + _this.scrollPosY).toString()+"px";
			
			try{ TweenMax.killTweensOf( target ); }catch(e){}
			TweenMax.to( target , duration, {css:css, ease:Cubic.easeOut, onComplete:gotoScrollInitPos, onUpdate:updateScrollBar} );
			
			currentScrollPow = 0;
		}
		
		
		var gotoScrollInitPos = function()
		{
			var target, duration, css;
			
			target = _this.contentsContainer;
			duration = 0.3;
			css = {};
			
			if( _this.needScroll == true && _this.scrollPosY < _this.minScrollPos )
			{
				css.marginTop = _this.minScrollPos.toString()+"px";	
				_this.scrollPosY = _this.minScrollPos;
				
			}
			else
			{
				css.marginTop = _this.maxScrollPos.toString()+"px";
				_this.scrollPosY = _this.maxScrollPos;
			}
		
			try{ TweenMax.killTweensOf( target ); }catch(e){}
			TweenMax.to( target , duration, {css:css, ease:Cubic.easeOut, onUpdate:updateScrollBar, onComplete : onScrollComplete} );
		}
		
		var onScrollComplete = function()
		{
			if( scrollBar != null ) 
			{
				try{ TweenMax.killTweensOf( scrollBar.bar ); }catch(e){}
				TweenMax.to( scrollBar.bar, 0.3, {css:{opacity:0}} );
			}
		}
		
		
		
		// 만약 스크롤 경계를 넘어가면 true 를 반환.
		var checkOutOfBound = function()
		{
			if( _this.scrollPosY < _this.minScrollPos || _this.scrollPosY > _this.maxScrollPos )
			{
				return 	true;
			}
			return false;			
		}
		
			
			
		
			
		//----------- event handlers
			
		var onTouchStart = function( e )
		{
			var target;
			
			e.preventDefault();
			
			if( e.targetTouches )
			{
				target = e.targetTouches[0];	
			}
			else
			{
				target = e;	
			}
			
			touchStartPos.x = target.screenX;
			touchStartPos.y = target.screenY;
			touchEndPos.x = target.screenX;
			touchEndPos.y = target.screenY;
			
			initPosY = target.screenY;
			prevPosY = initPosY;
			prevPosY2 = prevPosY;
			prevPosY3 = prevPosY2;
			
			
			document.addEventListener("touchmove", onMove, true );
			document.addEventListener("mousemove", onMove, true );
			document.addEventListener("touchend", onTouchEnd, true);
			document.addEventListener("mouseup", onTouchEnd, true);	
			
		}
		
		var onTouchEnd = function( e )
		{
			
			
			if( touchStartPos.x != touchEndPos.x || touchStartPos.y != touchEndPos.y )
			{
				e.preventDefault();
				
				try{
					e.stopPropagation();
					e.stopImmediatePropagation();	
				}catch( e ){}
				
			}
			
			
			document.removeEventListener("touchmove", onMove, true );
			document.removeEventListener("mousemove", onMove, true );
			document.removeEventListener("touchend", onTouchEnd, true);
			document.removeEventListener("mouseup", onTouchEnd, true);	
			
			isMoveEnter = false;

			onEnter();
		}
		
		var onMove = function( e )
		{
			var target;
			
			e.preventDefault();
			
			if( e.targetTouches )
			{
				target = e.targetTouches[0];	
			}
			else
			{
				target = e;	
			}
			
			touchEndPos.x = target.clientX;
			touchEndPos.y = target.clientY;
			
			
			currentScrollPow = (target.screenY - prevPosY);
	
			// 기본적으로 7픽셀 이상 움직여야 스크롤 시작으로 간주함.
			if( isMoveEnter == false && Math.abs( target.screenY-initPosY ) > 7 )
			{
				isMoveEnter = true;
				onMoveEnter();
				
				if( scrollBar != null ) 
				{
					try{ TweenMax.killTweensOf( scrollBar.bar ); }catch(e){}
					TweenMax.to( scrollBar.bar, 0.3, {css:{opacity:1}} );	
				}
				
			}
			
			
			prevPosY3 = prevPosY2;
			prevPosY2 = prevPosY;
			prevPosY = target.screenY;
			
		}
		
		this.scrollContainer.style.position = "absolute";
		this.scrollContainer.style.overflow = "hidden";
		
		this.apply();
		
		

		
		if( scrollBar != null ) 
		{
			scrollBar.setXY( this.scrollContainer.clientWidth-7, 0 );
			scrollBar.setSize( null, this.scrollContainer.clientHeight );
			updateScrollBar();
			this.scrollContainer.insertBefore( scrollBar.bar,  this.contentsContainer );
			
			try{ TweenMax.killTweensOf( scrollBar.bar ); }catch(e){}
			TweenMax.to( scrollBar.bar, 0, {css:{alpha:0}} );
		}
		
		this.setMouseEnabled( true );
		
	});


	
	//------------------------------------------------------------
	// prototype
	//------------------------------------------------------------
		
	ScrollComponentVertical.prototype = {
		
		/*
		* 자식을 배열형태로 추가하기.
		*/
		addChildList : function( ary ){
			
			var i, len;
			i=0;
			len = ary.length;
			while( i<len )
			{
				child = ary[ i ];
				this.contentsContainer.appendChild( child );
				++i;
			}
			
			this.apply();
		},
		
		
		/*
		* 단일 엘리먼트 자식 추가하기.
		*/
		addChild : function( element ){
			
			this.contentsContainer.appendChild( element );
		
			this.apply();
		},
		
		
		/*
		* 자식 컨테이너를 통으로 스왑하기.
		*/
		swapChildContainer : function( container ){
			
			this.scrollContainer.removeChild( this.scrollContainer.childNodes[ 0 ] );

			this.contentsContainer = container;
			this.contentsContainer.id = "contentsContainer";
			this.scrollContainer.appendChild( this.contentsContainer );
			
			this.apply();
		},
		
		
		
		setItemGap : function( gap ){
			
			this.gapItem = gap;
			
			this.apply();
		},
		
		
		setContentsHeight : function( h ){
			this.contentsHeight = h;	
			
			this.apply();
		},
		
		calculateContentsHeight : function(){
			
			var hei, i, len, child, element;
			
			if( this.contentsHeight == -1 )
			{
				i=0;
				len = this.contentsContainer.childNodes.length;
				hei = 0;
				
				while( i<len )
				{
					child = this.contentsContainer.childNodes[ i ];
					
					if( child.toString() !== "[object Text]" && child.toString() !== "[object Comment]" && child !== null )
					{
						element = child;
						element.style.marginBottom = this.gapItem+"px";
						hei += element.offsetHeight + this.gapItem;
					}
					++i;	
				}
				
				if( element != "undefined" && element != null && element.toString() !== "[object Comment]"  )
				{
					element.style.marginBottom = 0;
				}
				
				hei -= this.gapItem;
				
			}
			else
			{
				hei = this.contentsHeight;
			}
			
			if( this.scrollContainer.offsetHeight < hei ) this.needScroll = true;
			else this.needScroll = false;
			
			
			return hei;
			
		},
		
		
		
		apply : function()
		{			
			this.contentsContainer.style.height = this.calculateContentsHeight()+"px";
			this.maxScrollPos = 0;
			this.minScrollPos = this.scrollContainer.clientHeight - this.contentsContainer.clientHeight;
		}
		
	}
	
	
	
	/*
	* 스크롤 바 만들기.
	*/ 
	ScrollComponentVertical.createScrollBar = ( function( top, center, btm, onReady ){
		return new ScrollBarHorizontal( top, center, btm, onReady );
	} );
		
	
	
	
	
	
	
	
	
	
	
	